home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr01 / jock.zip / TOTSRC11.ZIP / TOTLINK.PAS < prev    next >
Pascal/Delphi Source File  |  1993-05-04  |  35KB  |  1,247 lines

  1. {               Copyright 1991 TechnoJock Software, Inc.               }
  2. {                          All Rights Reserved                         }
  3. {                         Restricted by License                        }
  4.  
  5. {                             Build # 1.10                             }
  6.  
  7. Unit totLINK;
  8. {$I TOTFLAGS.INC}
  9.  
  10. {
  11.  Development Notes:
  12.        1.00a     Apr  2 91   Changed file read logic when only Directory
  13.                              requested in FileDLLOBJ.
  14.        1.00b     May 29 91   Corrected DelNode when nil pointer passed
  15.        1.00c     Jun 11 91   Allowed display of directories when mask <> '*.*'
  16.        1.00d     Oct 10 91   Reset vSorted when list modified
  17. }
  18.  
  19. INTERFACE
  20.  
  21. Uses DOS,CRT,
  22.      totSTR;
  23.  
  24. Const
  25.   NoFiles: string[20] = 'No Files';
  26.  
  27. Type
  28.  
  29. tFileInfo = record
  30.      FileName: string[12];
  31.      Attr: byte;
  32.      Time: longint;
  33.      Size: longint;
  34.      LoadID: longint;
  35. end; {tFileInfo}
  36.  
  37. DLLNodePtr = ^DLLNodeObj;
  38. pDLLNodeOBJ = ^DLLNodeOBJ;
  39. DLLNodeOBJ = Object         {this object is not extensible}
  40.    vNextPtr: DLLNodePtr;
  41.    vPrevPtr: DLLNodePtr;
  42.    vDataPtr: pointer;
  43.    vSize: longint;
  44.    vStatus: byte;   {selectable, selected}
  45.    {methods...}
  46.    procedure FreeData;
  47.    function  NextPtr: DLLNodePtr;
  48.    function  PrevPtr: DLLNodePtr;
  49.    function  GetStatus(BitPos:byte): boolean;
  50.    procedure SetStatus(BitPos:byte;On:boolean);
  51.    function  GetStatusByte: byte;
  52.    procedure SetStatusByte(Val:byte); 
  53. end; {DLLNodeOBJ}
  54.  
  55. DLLPtr = ^DLLOBJ;
  56. pDLLOBJ = ^DLLOBJ;
  57. DLLOBJ = Object
  58.    vStartNodePtr:  DLLNodePtr;
  59.    vEndNodePtr:    DLLNodePtr;
  60.    vActiveNodePtr: DLLNodePtr;
  61.    vTotalNodes:       longint;
  62.    vActiveNodeNumber: longint;
  63.    vSortID:           shortInt;
  64.    vSortAscending:    boolean;
  65.    vSorted:           boolean;
  66.    vMaxNodeSize :     longint;
  67.    {methods...}
  68.    constructor Init;
  69.    function    Add(var TheData;Size:longint): integer;
  70.    function    Change(Node:DLLNodePtr;var TheData;Size:longint): integer;
  71.    function    InsertBefore(Node:DLLNodePtr;var TheData;Size:longint): integer;
  72.    procedure   Get(var TheData);
  73.    procedure   GetNodeData(Node:DLLNodePtr;Var TheData);
  74.    function    GetNodeDataSize(Node:DLLNodePtr):longint;
  75.    function    GetMaxNodeSize: longint;
  76.    procedure   Advance(Amount:longint);
  77.    procedure   Retreat(Amount:longint);
  78.    function    NodePtr(NodeNumber:longint): DLLNodePtr;
  79.    procedure   Jump(NodeNumber:longint);
  80.    procedure   ShiftActiveNode(NewNode: DLLNodePtr; NodeNumber: longint);
  81.    procedure   DelNode(Node:DLLNodePtr);
  82.    procedure   DelAllStatus(BitPos:byte;On:boolean);
  83.    function    TotalNodes: longint;
  84.    function    ActiveNodeNumber: longint;
  85.    function    ActiveNodePtr: DLLNodePtr;
  86.    function    StartNodePtr: DLLNodePtr;
  87.    function    EndNodePtr: DLLNodePtr;
  88.    procedure   EmptyList;
  89.    procedure   Sort(SortID:shortint;Ascending:boolean);
  90.    function    WrongOrder(Node1,Node2:DLLNodePtr;Asc:boolean): boolean; VIRTUAL;
  91.    procedure   SwapNodes(Node1,Node2:DLLNodePtr);                       VIRTUAL;
  92.    function    GetStr(Node:DLLNodePtr;Start,Finish: longint):string;    VIRTUAL;
  93.    destructor  Done;
  94. end; {DLLOBJ}
  95.  
  96. StrDLLPtr = ^StrDLLOBJ;
  97. pStrDLLOBJ = ^StrDLLOBJ;
  98. StrDLLOBJ = object (DLLOBJ)
  99.    {methods ...}
  100.    constructor Init;
  101.    function    Add(Str:string): integer;
  102.    function    Change(Node:DLLNodePtr;Str: string): integer;
  103.    function    InsertBefore(Node:DLLNodePtr;Str:string): integer;
  104.    function    WrongOrder(Node1,Node2:DLLNodePtr;Asc:boolean): boolean; VIRTUAL;
  105.    function    GetStr(Node:DLLNodePtr;Start,Finish: longint):string;    VIRTUAL;
  106.    destructor  Done;
  107. end; {StrDLLOBJ}
  108.  
  109. FileDLLPtr = ^FileDLLOBJ; 
  110. pFileDLLOBJ = ^FileDLLOBJ;
  111. FileDLLOBJ = object (DLLOBJ)
  112.    vFileMasks: string;
  113.    vFileAttrib: word;
  114.    {methods ...}
  115.    constructor Init;
  116.    procedure   FillList;
  117.    procedure   SetFileDetails(FileMasks:string; FileAttrib: word);
  118.    procedure   FillNewMask(FileMasks:string);
  119.    function    GetLongStr(Node:DLLNodePtr):string;
  120.    procedure   GetFileRecord(var FileInfo:tFileInfo; Item:longint);
  121.    function    GetFileMask:string;
  122.    function    WrongOrder(Node1,Node2:DLLNodePtr;Asc:boolean): boolean; VIRTUAL;
  123.    procedure   SwapNodes(Node1,Node2:DLLNodePtr);                       VIRTUAL;
  124.    function    GetStr(Node:DLLNodePtr;Start,Finish: longint):string;    VIRTUAL;
  125.    destructor  Done;
  126. end; {FileDLLOBJ}
  127.  
  128. function Subdirectory(B : byte):boolean;
  129. function FileAttribs(B:byte):string;
  130. function LongName(Info: tFileInfo):string;
  131. procedure LINKInit;
  132.  
  133. IMPLEMENTATION
  134. {|||||||||||||||||||||||||||||||||||||||||||||}
  135. {                                             }
  136. {     M i s c.  P r o c s   &   F u n c s     }
  137. {                                             }
  138. {|||||||||||||||||||||||||||||||||||||||||||||}
  139. function Subdirectory(B : byte):boolean;
  140. begin
  141.    Subdirectory := ((B and Directory) = Directory);
  142. end; {Subdirectory}
  143.  
  144. function FileAttribs(B:byte):string;
  145. var
  146.   S : string;
  147. begin
  148.    S := '    ';
  149.    If ((B and ReadOnly) = Readonly) then
  150.       S[1] := 'R';
  151.    If ((B and Hidden) = Hidden) then
  152.       S[2] := 'H';
  153.    If ((B and SysFile) = SysFile) then
  154.       S[3] := 'S';
  155.    If ((B and Archive) = Archive) then
  156.       S[4] := 'A';
  157.    FileAttribs := S;
  158. end; {FileAttribs}
  159.  
  160. function LongName(Info: tFileInfo):string;
  161. {}
  162. var 
  163.   DT :datetime;
  164.   S: String;
  165. begin
  166.    S := padleft(Info.FileName,12,' ');
  167.    UnPackTime(Info.Time,DT);
  168.    if Subdirectory(Info.Attr) then                  {add file size}
  169.       S := S + Padright('<DIR>',8,' ')
  170.    else
  171.       S := S + Padright(InttoStr(Info.Size),8,' ');
  172.    S := S + ' ';
  173.    with DT do
  174.    begin
  175.       Case Month of        
  176.          1 : S := S + 'Jan ';
  177.          2 : S := S + 'Feb ';
  178.          3 : S := S + 'Mar ';
  179.          4 : S := S + 'Apr ';
  180.          5 : S := S + 'May ';
  181.          6 : S := S + 'Jun ';
  182.          7 : S := S + 'Jul ';
  183.          8 : S := S + 'Aug ';
  184.          9 : S := S + 'Sep ';
  185.          10: S := S + 'Oct ';
  186.          11: S := S + 'Nov ';
  187.          12: S := S + 'Dec ';
  188.       end; {case}
  189.       S := S + Padright(InttoStr(Day),2,'0')+','+IntToStr(Year)+' ';
  190.       if Hour > 12 then
  191.          S := S + Padright(IntToStr(Hour-12),2,' ')+':'+Padright(IntToStr(min),2,'0')+'p'
  192.       else
  193.          S := S + Padright(IntToStr(Hour),2,' ')+':'+Padright(IntToStr(min),2,'0')+'a';
  194.       S := S + ' '+FileAttribs(Info.Attr);
  195.    end;
  196.    LongName := S;
  197. end; {LongName}
  198. {||||||||||||||||||||||||||||||||||||||||||||||}
  199. {                                              }
  200. {     D L L  N o d e O b j   M E T H O D S     }
  201. {                                              }
  202. {||||||||||||||||||||||||||||||||||||||||||||||}
  203. procedure DLLNodeObj.FreeData;
  204. {}
  205. begin
  206.    if (vDataPtr <> Nil) and (vSize > 0) then
  207.    begin
  208.       Freemem(vDataPtr,vSize);
  209.       vDataPtr := nil;
  210.       vSize:= 0;
  211.    end;
  212. end; {DLLNodeObj.FreeData}
  213.  
  214. function DLLNodeObj.NextPtr: DLLNodePtr;
  215. {}
  216. begin
  217.    NextPtr := vNextPtr;
  218. end; {DLLNodeOBJ.NextPtr}
  219.  
  220. function DLLNodeObj.PrevPtr: DLLNodePtr;
  221. {}
  222. begin
  223.    PrevPtr := vPrevPtr;
  224. end; {DLLNodeOBJ.PrevPtr}
  225.  
  226. function DLLNodeObj.GetStatus(BitPos:byte): boolean;
  227. {}
  228. var TestByte: Byte;
  229. begin
  230.    if BitPos > 7 then
  231.       GetStatus := false
  232.    else
  233.    begin
  234.      Testbyte := vStatus;
  235.      TestByte := TestByte SHR BitPos; {move to end bit}
  236.      GetStatus := odd(TestByte);
  237.    end;
  238. end; {DLLNodeOBJ.GetStatus}
  239.  
  240. procedure DLLNodeObj.SetStatus(BitPos:byte; On:boolean);
  241. {}
  242. var
  243.    Test : integer;
  244. begin
  245.    if BitPos <= 7 then
  246.    begin
  247.       if On then
  248.       begin
  249.          Test := 1 SHL BitPos;
  250.          vStatus := vStatus or Test
  251.       end
  252.       else
  253.       begin
  254.          Test := not (1 SHL BitPos);
  255.          vStatus := vStatus and Test;
  256.       end;
  257.    end;
  258. end; { DLLNodeObj.SetStatus }
  259.  
  260. function DLLNodeObj.GetStatusByte: byte;
  261. {}
  262. begin
  263.    GetStatusByte := vStatus;
  264. end; {DLLNodeObj.GetStatusByte}
  265.  
  266. procedure DLLNodeObj.SetStatusByte(Val:byte);
  267. {}
  268. begin
  269.    vStatus := Val;
  270. end; {DLLNodeObj.SetStatusByte}
  271. {|||||||||||||||||||||||||||||||||||||}
  272. {                                     }
  273. {     D L L O b j   M E T H O D S     }
  274. {                                     }
  275. {|||||||||||||||||||||||||||||||||||||}
  276. constructor DLLOBJ.Init;
  277. {}
  278. begin
  279.    vStartNodePtr := nil;
  280.    vEndNodePtr := nil;
  281.    vActiveNodePtr := nil;
  282.    vTotalNodes := 0;
  283.    vActiveNodeNumber := 0;
  284.    vSortID := 0;
  285.    vSortAscending := true;
  286.    vSorted := true;
  287.    vMaxNodeSize := 0;
  288. end; {DLLOBJ.Init}
  289.  
  290. function DLLOBJ.Add(var TheData; Size:Longint): integer;
  291. { Adds node after the ActiveNodePtr, and increments the
  292.   ActiveNodePtr.
  293.  
  294.   Returns status indicating result of attemp to add.
  295.   Codes:          0      Success
  296.                   1      Not enough memory
  297.                   2      Not enough memory for data
  298. }
  299. var
  300.   Temp: DLLNodePtr;
  301. begin
  302.    if MaxAvail < sizeOf(vStartNodePtr^) then
  303.    begin
  304.       Add := 1;  {not enough memory}
  305.       exit;
  306.    end;
  307.    if vStartNodePtr = nil then
  308.    begin
  309.       getmem(vStartNodePtr,sizeof(vStartNodePtr^));
  310.       vStartNodePtr^.vPrevPtr := nil;
  311.       vActiveNodePtr := vStartNodePtr;
  312.       vActiveNodePtr^.vNextPtr := nil;
  313.       vActiveNodeNumber := 1;
  314.       vEndNodePtr := vActiveNodePtr;
  315.    end
  316.    else
  317.    begin
  318.       if vActiveNodePtr^.vNextPtr = nil then
  319.       begin
  320.          getmem(vActiveNodePtr^.vNextPtr,sizeof(vActiveNodePtr^));
  321.          vActiveNodePtr^.vNextPtr^.vPrevPtr := vActiveNodePtr;
  322.          vActiveNodePtr := vActiveNodePtr^.vNextPtr;
  323.          vActiveNodePtr^.vNextPtr := nil;
  324.          inc(vActiveNodeNumber);
  325.          vEndNodePtr := vActiveNodePtr;
  326.       end
  327.       else  {insert a node}
  328.       begin
  329.          getmem(Temp,sizeof(temp^));
  330.          vActiveNodePtr^.vNextPtr^.vPrevPtr := Temp;
  331.          Temp^.vNextPtr := vActiveNodePtr^.vNextPtr;
  332.          Temp^.vPrevPtr := vActiveNodePtr;
  333.          vActiveNodePtr^.vNextPtr := Temp;
  334.          vActiveNodePtr := Temp;
  335.          inc(vActiveNodeNumber);
  336.       end;
  337.    end;
  338.    inc(vTotalNodes);
  339.    {now add the data to the node data pointer}
  340.    if MemAvail < Size then
  341.    begin
  342.      Add := 2;   {not enough memory for data}
  343.      vActiveNodePtr^.vSize := 0;
  344.      vActiveNodePtr^.vDataPtr := nil;
  345.      exit;
  346.    end;
  347.    if Size > 0 then
  348.    begin
  349.       getmem(vActiveNodePtr^.vDataPtr,Size);
  350.       move(TheData,vActiveNodePtr^.vDataPtr^,Size);
  351.       if Size > vMaxNodeSize then
  352.          vMaxNodeSize := Size;
  353.    end
  354.    else
  355.       vActiveNodePtr^.vDataPtr := nil;
  356.    vActiveNodePtr^.vSize := Size;
  357.    vActiveNodePtr^.vStatus := 0;
  358.    vSorted := false;  {1.00d}
  359.    Add := 0;
  360. end; {DLLOBJ.Add}
  361.  
  362. function DLLOBJ.Change(Node:DLLNodePtr;var TheData; Size:Longint): integer;
  363. { Returns status indicating result of attemp to add.
  364.   Codes:          0      Success
  365.                   2      Not enough memory for data
  366.                   3      Invalid Node Ptr
  367. }
  368. begin
  369.    if node = nil then
  370.       Change := 3
  371.    else 
  372.    begin
  373.      Node^.FreeData;
  374.      if MaxAvail < Size then
  375.         Change := 2
  376.      else
  377.      begin
  378.          Change := 0;
  379.          getmem(Node^.vDataPtr,Size);
  380.          move(TheData,Node^.vDataPtr^,Size);
  381.          Node^.vSize := Size;
  382.          vSorted := false;  {1.00d}
  383.      end;
  384.    end;
  385. end; {DLLOBJ.Change}
  386.  
  387. function DLLOBJ.InsertBefore(Node:DLLNodePtr;var TheData;Size:longint): integer;
  388. { Returns status indicating result of attemp to add.
  389.   Codes:          0      Success
  390.                   1      Not enough memory
  391.                   2      Not enough memory for data
  392.                   3      Invalid Node Ptr
  393. }
  394. var
  395.   Temp: DLLNodePtr;
  396. begin
  397.    if node = nil then
  398.       InsertBefore := 3
  399.    else if MaxAvail < sizeOf(Node^) then
  400.       InsertBefore:= 1  {not enough memory}
  401.    else
  402.    begin
  403.       if Node = vStartNodePtr then {add to head of list}
  404.       begin
  405.          getmem(Node^.vPrevPtr,sizeof(Node^));
  406.          Node^.vPrevPtr^.vNextPtr := Node;
  407.          Node := Node^.vPrevPtr;
  408.          Node^.vPrevPtr := nil;
  409.          vStartNodePtr := Node;
  410.       end
  411.       else
  412.       begin
  413.          getmem(Temp,sizeof(Temp^));
  414.          Node^.vPrevPtr^.vNextPtr := Temp;
  415.          Temp^.vPrevPtr := Node^.PrevPtr;
  416.          Node^.vPrevPtr := Temp;
  417.          Temp^.vNextPtr := Node;
  418.          Node := Temp;
  419.       end;
  420.       inc(vTotalNodes);
  421.       vActiveNodeNumber := 1;
  422.       vActiveNodePtr := vStartNodePtr;
  423.       if MemAvail < Size then
  424.       begin
  425.          InsertBefore := 2;   {not enough memory for data}
  426.          Node^.vSize := 0;
  427.          Node^.vDataPtr := nil;
  428.       end
  429.       else
  430.       begin
  431.          if Size > 0 then
  432.          begin
  433.             getmem(Node^.vDataPtr,Size);
  434.             move(TheData,Node^.vDataPtr^,Size);
  435.          end
  436.          else
  437.            Node^.vDataPtr := nil;
  438.          Node^.vSize := Size;
  439.          InsertBefore := 0;
  440.       end;
  441.    end;
  442.    vSorted := false;  {1.00d}
  443. end; {DLLOBJ.InsertBefore}
  444.  
  445. procedure DLLOBJ.Get(Var TheData);
  446. {}
  447. begin
  448.     with vActiveNodePtr^ do
  449.        if vDataPtr <> Nil then
  450.           move(vDataPtr^,TheData,vSize);
  451. end; {DLLOBJ.Get}
  452.  
  453. procedure DLLOBJ.GetNodeData(Node:DLLNodePtr;Var TheData);
  454. {}
  455. begin
  456.     with Node^ do
  457.        if vDataPtr <> Nil then
  458.           move(vDataPtr^,TheData,vSize);
  459. end; {DLLOBJ.GetNodedata}
  460.  
  461. function DLLOBJ.GetNodeDataSize(Node:DLLNodePtr):longint;
  462. {}
  463. begin
  464.    with Node^ do
  465.    begin
  466.       if vDataPtr = Nil then
  467.          GetNodeDataSize := 0
  468.       else
  469.          GetNodeDataSize := vSize;
  470.    end;
  471. end; {DLLOBJ.GetNodeDataSize}
  472.  
  473. function DLLOBJ.GetMaxNodeSize: longint;
  474. {}
  475. begin
  476.    GetMaxNodeSize := vMaxNodeSize;
  477. end; {DLLOBJ.GetMaxNodeSize}
  478.  
  479. function DLLOBJ.GetStr(Node:DLLNodePtr;Start,Finish:longint): String;
  480. {generic method..usually in descendant object}
  481. var temp: string;
  482. begin
  483.    if Start < 0 then Start := 0;
  484.    if Finish < 0 then Finish := 0;
  485.    {validate Start and Finish Parameters}
  486.    if ((Finish = 0) and (Start = 0))
  487.    or (Start > Finish) then   {get full string}
  488.    begin
  489.       Start := 1;
  490.       Finish := 255;
  491.    end
  492.    else if Finish - Start > 254 then      {too long to fit in string}
  493.       Finish := Start + 254;
  494.  
  495.    if (Node = Nil)
  496.    or (Node^.vDataPtr = Nil)
  497.    or (Node^.vSize = 0)
  498.    or (Start > Node^.vSize) then
  499.       GetStr := ''
  500.    else
  501.    begin
  502.       if Finish > Node^.vSize then
  503.          Finish := Node^.vSize;
  504.       if Start = 0 then
  505.          inc(Start);
  506.       Move(mem[seg(Node^.vDataPtr^):ofs(Node^.vDataPtr^)+pred(Start)],Temp[1],succ(Finish-Start));
  507.       Temp [0] := chr(succ(Finish-Start));
  508.       GetStr := Temp;
  509.    end;
  510. end; {DLLOBJ.GetStr}
  511.  
  512. procedure DLLOBJ.Advance(Amount:longint);
  513. {}
  514. var
  515.   I : longint;
  516. begin
  517.    for I := 1 to Amount do
  518.       if vActiveNodePtr^.vNextPtr <> nil then
  519.       begin
  520.           vActiveNodePtr := vActiveNodePtr^.vNextPtr;
  521.           inc(vActiveNodeNumber);
  522.       end;
  523. end; {DLLOBJ.Advance}
  524.  
  525. procedure DLLOBJ.Retreat(Amount:longint);
  526. {}
  527. var
  528.   I : longint;
  529. begin
  530.    for I := 1 to Amount do
  531.       if vActiveNodePtr^.vPrevPtr <> nil then
  532.       begin
  533.           vActiveNodePtr := vActiveNodePtr^.vPrevPtr;
  534.           dec(vActiveNodeNumber);
  535.       end;
  536. end; {DLLOBJ.Retreat}
  537.  
  538. procedure DLLOBJ.Jump(NodeNumber:longint);
  539. {}
  540. begin
  541.    if NodeNumber = 1 then
  542.    begin
  543.       vActiveNodePtr := vStartNodePtr;
  544.       vActiveNodeNumber := 1;
  545.    end
  546.    else
  547.    begin
  548.       if NodeNumber < vActiveNodeNumber then
  549.          Retreat(vActiveNodeNumber - NodeNumber)
  550.       else
  551.          Advance(NodeNumber - vActiveNodeNumber);
  552.    end;
  553. end; {DLLOBJ.Jump}
  554.  
  555. procedure DLLOBJ.ShiftActiveNode(NewNode: DLLNodePtr; NodeNumber: longint);
  556. {}
  557. begin
  558.    vActiveNodePtr := NewNode;
  559.    vActiveNodeNumber := NodeNumber;
  560. end; {DLLOBJ.ShiftActiveNode}
  561.  
  562. function DLLOBJ.NodePtr(NodeNumber:longint): DLLNodePtr;
  563. {}
  564. var
  565.   StartNode: DLLNodePtr;
  566.   DistanceA,
  567.   DistanceB,
  568.   DistanceC,
  569.   Counter,
  570.   I: LongInt;
  571.   Forwards : boolean;
  572.   Indicator : byte;
  573. begin
  574.    if (NodeNumber < 1) or (NodeNumber > vTotalNodes) then
  575.       NodePtr := nil
  576.    else
  577.    begin
  578.       if NodeNumber = 1 then
  579.          NodePtr := vStartNodePtr
  580.       else if NodeNumber = vTotalNodes then
  581.             NodePtr := vEndNodePtr
  582.       else if NodeNumber = vActiveNodeNumber then
  583.             NodePtr := vActiveNodePtr
  584.       else
  585.       begin
  586.          {check for the nearest node ptr, and jump from there}
  587.          DistanceA := abs(NodeNumber - vActiveNodeNumber);
  588.          DistanceB := NodeNumber;
  589.          DistanceC := vTotalNodes - NodeNumber;
  590.          if DistanceA < DistanceB then
  591.          begin
  592.             if DistanceA < DistanceC then
  593.             begin
  594.                StartNode := vActiveNodePtr;
  595.                Forwards := (vActiveNodeNumber < NodeNumber);
  596.                Counter := DistanceA;
  597.             end
  598.             else
  599.             begin
  600.                StartNode := vEndNodePtr;
  601.                Forwards := false;
  602.                Counter := DistanceC;
  603.             end;
  604.          end
  605.          else      {DA > DB}
  606.          begin
  607.             if DistanceB < DistanceC then
  608.             begin
  609.                StartNode := vStartNodePtr;
  610.                Forwards := true;
  611.                Counter := pred(DistanceB);
  612.             end
  613.             else
  614.             begin
  615.                StartNode := vEndNodePtr;
  616.                Forwards := false;
  617.                Counter := DistanceC;
  618.             end;
  619.          end;
  620.          if Forwards then
  621.             for I := 1 to Counter do
  622.                 StartNode := StartNode^.NextPtr
  623.          else
  624.             for I := 1 to Counter do
  625.                 StartNode := StartNode^.PrevPtr;
  626.          NodePtr := StartNode;
  627.  
  628.       end;
  629.   end;
  630. end; {DLLOBJ.NodePtr}
  631.  
  632. function DLLOBJ.TotalNodes: longint;
  633. {}
  634. begin
  635.     TotalNodes := vTotalNodes;
  636. end;
  637.  
  638. function DLLOBJ.ActiveNodeNumber: longint;
  639. {}
  640. begin
  641.     ActiveNodeNumber := vActiveNodeNumber;
  642. end;
  643.  
  644. function DLLOBJ.StartNodePtr: DLLNodePtr;
  645. {}
  646. begin
  647.    StartNodePtr := vStartNodePtr;
  648. end; {DLLOBJ.StartNodePtr}
  649.  
  650. function DLLOBJ.EndNodePtr: DLLNodePtr;
  651. {}
  652. begin
  653.    EndNodePtr := vEndNodePtr;
  654. end; {DLLOBJ.EndNodePtr}
  655.  
  656. function DLLOBJ.ActiveNodePtr: DLLNodePtr;
  657. {}
  658. begin
  659.     ActiveNodePtr := vActiveNodePtr;
  660. end; {DLLOBJ.ActiveNodePtr}
  661.  
  662. (* The following procedure requires only 8 bytes on the 
  663.    stack but damn it's slow!
  664. procedure DLLOBJ.SwapNodes(Node1,Node2:DLLNodePtr);
  665. {swaps the position of two nodes in the tree}
  666. var
  667.    TempPrevPtr,
  668.    TempNextPtr : DLLNodePtr;
  669. begin
  670.    if vStartNodePtr = Node1 then
  671.       vStartNodePtr := Node2
  672.    else if vStartNodePtr = Node2 then
  673.       vStartNodePtr := Node1;
  674.    if vEndNodePtr = Node1 then
  675.       vEndNodePtr := Node2
  676.    else if vEndNodePtr = Node2 then
  677.       vEndNodePtr := Node1;
  678.    if vActiveNodePtr = Node1 then
  679.       vActiveNodePtr := Node2
  680.    else if vActiveNodePtr = Node2 then
  681.       vActiveNodePtr := Node1;
  682.    if (Node1^.vNextPtr = Node2) then  {nodes next to each other}
  683.    begin
  684.       TempNextPtr := Node2^.vNextPtr;
  685.       {move Node2 into Node1's place}
  686.       Node2^.vPrevPtr := Node1^.vPrevPtr;
  687.       Node2^.vNextPtr := Node1;
  688.       if Node2^.vPrevPtr <> nil then
  689.          Node2^.vPrevPtr^.vNextPtr := Node2;
  690.       if Node2^.vNextPtr <> nil then
  691.          Node2^.vNextPtr^.vPrevPtr := Node2;
  692.       {move Node1 into Node2's place}
  693.       Node1^.vPrevPtr := Node2;
  694.       Node1^.vNextPtr := TempNextPtr;
  695.       if Node1^.vNextPtr <> nil then
  696.          Node1^.vNextPtr^.vPrevPtr := Node1;
  697.    end
  698.    else
  699.       if (Node1^.vPrevPtr = Node2) then  {nodes next to each other}
  700.       begin
  701.          TempPrevPtr := Node2^.vPrevPtr;
  702.          {move Node2 into Node1's place}
  703.          Node2^.vPrevPtr := Node1;
  704.          Node2^.vNextPtr := Node1^.vNextPtr;
  705.          if Node2^.vNextPtr <> nil then
  706.             Node2^.vNextPtr^.vPrevPtr := Node2;
  707.          {move Node1 into Node2's place}
  708.          Node1^.vPrevPtr := TempPrevPtr;
  709.          Node1^.vNextPtr := Node2;
  710.          if Node1^.vPrevPtr <> nil then
  711.             Node1^.vPrevPtr^.vNextPtr := Node1;
  712.       end
  713.       else  {the nodes are not adjacent to each other}
  714.       begin
  715.          TempPrevPtr := Node2^.vPrevPtr;
  716.          TempNextPtr := Node2^.vNextPtr;
  717.          {move Node2 into Node1's place}
  718.          Node2^.vPrevPtr := Node1^.vPrevPtr;
  719.          Node2^.vNextPtr := Node1^.vNextPtr;
  720.          if Node2^.vPrevPtr <> nil then
  721.             Node2^.vPrevPtr^.vNextPtr := Node2;
  722.          if Node2^.vNextPtr <> nil then
  723.             Node2^.vNextPtr^.vPrevPtr := Node2;
  724.          {move Node1 into Node2's place}
  725.          Node1^.vPrevPtr := TempPrevPtr;
  726.          Node1^.vNextPtr := TempNextPtr;
  727.          if Node1^.vPrevPtr <> nil then
  728.             Node1^.vPrevPtr^.vNextPtr := Node1;
  729.          if Node1^.vNextPtr <> nil then
  730.             Node1^.vNextPtr^.vPrevPtr := Node1;
  731.       end;
  732. end; {DLLOBJ.SwapNodes}
  733. *)
  734.  
  735. procedure DLLOBJ.SwapNodes(Node1,Node2:DLLNodePtr);
  736. {}
  737. var 
  738.   Ptr1: pointer;
  739.   Size1,Size2: longint;
  740.   Status1: byte;
  741.   Ecode: integer;
  742. begin
  743.    Status1 := Node1^.GetStatusByte;
  744.    Node1^.SetStatusByte(Node2^.GetStatusByte);
  745.    Node2^.SetStatusByte(Status1);
  746.    Size1 := GetNodeDataSize(Node1);
  747.    if Size1 > 0 then
  748.    begin
  749.       getmem(Ptr1,size1);
  750.       GetNodeData(Node1,Ptr1^);
  751.    end;
  752.    Size2 := GetNodeDataSize(Node2);
  753.    Ecode := Change(Node1,Node2^.vDataPtr^,Size2);
  754.    Ecode := Change(Node2,Ptr1^,Size1);
  755.    if Size1 > 0 then
  756.       freemem(Ptr1,Size1);
  757. end; {DLLOBJ.SwapNodes}
  758.  
  759. procedure DLLOBJ.DelNode(Node: DLLNodePtr);
  760. {}
  761. begin
  762.    if Node <> nil then  {1.00b}
  763.    begin
  764.       if vActiveNodePtr = Node then   {move active ptr to next entry in list}
  765.       begin
  766.          if vActiveNodePtr^.vNextPtr = nil then
  767.          begin
  768.             dec(vActiveNodeNumber);
  769.             vActiveNodePtr := vActiveNodePtr^.vPrevPtr;
  770.          end
  771.          else
  772.             vActiveNodePtr := vActiveNodePtr^.vNextPtr;
  773.       end;
  774.       if Node = vStartNodePtr then
  775.       begin
  776.          if Node^.vNextPtr = nil then {only node in list}
  777.          begin
  778.             Node^.FreeData;
  779.             Freemem(vStartNodePtr,sizeof(vStartNodePtr^));
  780.             vStartNodePtr := nil;
  781.             vEndNodePtr := nil;
  782.          end
  783.          else
  784.          begin
  785.             vStartNodePtr := vStartNodePtr^.vNextPtr;
  786.             vStartNodePtr^.vPrevPtr := nil;
  787.             Node^.FreeData;
  788.             Freemem(Node,sizeof(Node^));
  789.          end;
  790.       end
  791.       else
  792.       begin
  793.          Node^.vPrevPtr^.vNextPtr := Node^.vNextPtr;
  794.          if Node = vEndNodePtr then
  795.             vEndNodePtr := vEndNodePtr^.vPrevPtr
  796.          else
  797.             Node^.vNextPtr^.vPrevPtr := Node^.vPrevPtr;
  798.          Node^.FreeData;
  799.          Freemem(Node,sizeof(Node^));
  800.       end;
  801.       dec(vTotalNodes);
  802.       vSorted := false;  {1.00d}
  803.    end;
  804. end; {DLLOBJ.DelNode}
  805.  
  806. procedure DLLOBJ.DelAllStatus(BitPos:byte;On:boolean);
  807. {}
  808. var
  809.   TempPtr,TempNextPtr: DLLNodePtr;
  810. begin
  811.    if vStartNodePtr <> nil then
  812.    begin
  813.       TempPtr := vStartNodePtr;
  814.       TempNextPtr := TempPtr^.NextPtr;
  815.       while TempNextPtr <> nil do
  816.       begin
  817.          if TempNextPtr^.GetStatus(BitPos) = On then
  818.             DelNode(TempNextPtr)
  819.          else
  820.             TempPtr := TempPtr^.NextPtr;
  821.             TempNextPtr := TempPtr^.NextPtr;
  822.       end;
  823.        if vStartNodePtr^.GetStatus(BitPos) = On then
  824.             DelNode(vStartNodePtr);
  825.       vSorted := false;  {1.00d}
  826.    end;
  827. end; {DLLOBJ.DelAllStatus}
  828.  
  829. function DLLOBJ.WrongOrder(Node1,Node2:DLLNodePtr;Asc:boolean):boolean;
  830. {abstract}
  831. begin
  832.    WrongOrder := false;
  833. end; {DLLOBJ.WrongOrder}
  834.  
  835. procedure DLLOBJ.Sort(SortID:shortint;Ascending:boolean);
  836. {Shell sort}
  837. var
  838.    I,J,Delta : longint;
  839.    Swapped : boolean;
  840.    Ptr1,Ptr2 : DLLNodePtr;
  841. begin
  842.    if ((vSortID <> SortID) or (vSortAscending <> Ascending) or (vSorted = false))
  843.    and (vTotalNodes >= 2) then
  844.    begin
  845.       vSortID := SortID;
  846.       vSortAscending := Ascending;
  847.       Delta := vTotalNodes div 2;
  848.       repeat
  849.          Repeat
  850.             Swapped := false;
  851.             Ptr1 := vStartNodePtr;
  852.             Ptr2 := Ptr1;
  853.             for I := 1 to Delta do
  854.               Ptr2 := Ptr2^.vNextPtr;
  855.             for I := 1 to vTotalNodes - Delta do
  856.             begin
  857.               if I > 1 then
  858.               begin
  859.                  Ptr1 := Ptr1^.vNextPtr;
  860.                  Ptr2 := Ptr2^.vNextPtr;
  861.               end;
  862.               if WrongOrder(Ptr1,Ptr2,vSortAscending) then
  863.               begin
  864.                  SwapNodes(Ptr1,Ptr2);
  865.                  Swapped := true;
  866.               end;
  867.             end;
  868.          Until (not Swapped);
  869.          Delta := Delta div 2;
  870.       Until Delta = 0;
  871.    end;
  872.    vSorted := true;
  873. end; {DLLOBJ.Sort}
  874.  
  875. procedure DLLOBJ.EmptyList;
  876. {removes all the memory allocated on the heap by chaining back
  877.  through the list and disposing of each node.}
  878. var TempPtr: DLLNodePtr;
  879. begin
  880.    TempPtr := vEndNodePtr;
  881.    if vEndNodePtr <> nil then
  882.    while TempPtr^.vPrevPtr <> nil do
  883.    begin
  884.       TempPtr^.FreeData;
  885.       TempPtr := TempPtr^.vPrevPtr;
  886.       Freemem(TempPtr^.vNextPtr,sizeof(TempPtr^));
  887.    end;
  888.    if vStartNodePtr <> Nil then
  889.    begin
  890.       vStartNodePtr^.FreeData;
  891.       Freemem(vStartNodePtr,sizeof(vStartNodePtr^));
  892.       vStartNodePtr := Nil;
  893.    end;
  894.    vEndNodePtr := nil;
  895.    vActiveNodePtr := nil;
  896.    vTotalNodes := 0;
  897.    vActiveNodeNumber := 0;
  898.    vSorted := false;  {1.00d}
  899. end; {DLLOBJ.EmptyList}
  900.  
  901. destructor DLLOBJ.Done;
  902. {}
  903. begin
  904.    EmptyList;
  905. end; {of dest DLLOBJ.Done}
  906.  
  907. {|||||||||||||||||||||||||||||||||||||||||||}
  908. {                                           }
  909. {     S t r D L L O b j   M E T H O D S     }
  910. {                                           }
  911. {|||||||||||||||||||||||||||||||||||||||||||}
  912.  
  913. {The StrDLLOBJ object is a descendant of the DLLOBJ object, and
  914.  it is designed to specifically manipulate strings}
  915.  
  916. constructor StrDLLOBJ.Init;
  917. {}
  918. begin
  919.    DLLOBJ.Init;
  920. end; {StrDLLOBJ.Init}
  921.  
  922. function StrDLLOBJ.Add(Str: string): integer;
  923. {}
  924. var
  925.   Len : byte;
  926. begin
  927.    Len := Length(Str);
  928.    Add := DLLOBJ.Add(Str[1],Len);
  929. end; {StrDLLOBJ.Add}
  930.  
  931. function StrDLLOBJ.GetStr(Node:DLLNodePtr;Start,Finish:longint): String;
  932. {}
  933. begin
  934.    GetStr := DLLOBJ.GetStr(Node,Start,Finish);
  935. end; {StrDLLOBJ.GetStr}
  936.  
  937. function StrDLLOBJ.Change(Node:DLLNodePtr;Str: string): integer;
  938. {}
  939. var
  940.   Len:byte;
  941. begin
  942.    Len := length(Str);
  943.    Change := DLLOBJ.Change(Node,Str[1],Len);
  944. end; {StrDLLOBJ.Change}
  945.  
  946. function StrDLLOBJ.InsertBefore(Node:DLLNodePtr;Str:string): integer;
  947. {}
  948. var
  949.   Len:byte;
  950. begin
  951.    Len := length(Str);
  952.    InsertBefore := DLLOBJ.InsertBefore(Node,Str[1],Len);
  953. end; {StrDLLOBJ.InsertBefore}
  954.  
  955. function StrDLLOBJ.WrongOrder(Node1,Node2:DLLNodePtr;Asc:boolean): boolean;
  956. {}
  957. var S1,S2: string;
  958. begin
  959. (*
  960.    if Asc then
  961.    begin
  962.       GetNodeData(Node1,S1);
  963.       GetNodeData(Node2,S2);
  964.    end
  965.    else
  966.    begin
  967.       GetNodeData(Node1,S2);
  968.       GetNodeData(Node2,S1);
  969.    end;
  970. *)
  971.    if Asc then
  972.    begin
  973.       S1 := GetStr(Node1,1,255);
  974.       S2 := GetStr(Node2,1,255);
  975.    end
  976.    else
  977.    begin
  978.       S1 := GetStr(Node2,1,255);
  979.       S2 := GetStr(Node1,1,255);
  980.    end;
  981.    WrongOrder := (S1 > S2);
  982. end; {StrDLLOBJ.WrongOrder}
  983.  
  984. destructor StrDLLOBJ.Done;
  985. {}
  986. begin
  987.    DLLOBJ.Done;
  988. end; {StrDLLOBJ.Done}
  989. {|||||||||||||||||||||||||||||||||||||||||||||}
  990. {                                             }
  991. {     F i l e D L L O b j   M E T H O D S     }
  992. {                                             }
  993. {|||||||||||||||||||||||||||||||||||||||||||||}
  994. constructor FileDLLOBJ.Init;
  995. {}
  996. begin
  997.    DLLOBJ.Init;
  998.    vFileMasks := '*.*';
  999.    vFileAttrib := archive + readonly;
  1000. end; {FileDLLOBJ.Init}
  1001.  
  1002. function FileDLLOBJ.GetStr(Node:DLLNodePtr;Start,Finish: longint):string; 
  1003. {ignores Start and Finish parameters - first 13 bytes of the Data is
  1004.  the filename.}
  1005. var temp : string;
  1006. begin
  1007.    if (Node = Nil)
  1008.    or (Node^.vDataPtr = Nil)
  1009.    or (Node^.vSize = 0)  then
  1010.       GetStr := ''
  1011.    else
  1012.    begin
  1013.       Move(mem[seg(Node^.vDataPtr^):ofs(Node^.vDataPtr^)],Temp[0],13);
  1014.       GetStr := Temp;
  1015.    end;
  1016. end; {FileDLLOBJ.GetStr}
  1017.  
  1018. function FileDLLOBJ.GetLongStr(Node:DLLNodePtr):string;
  1019. {}
  1020. var Info: tFileInfo;
  1021. begin
  1022.    if (Node = Nil)
  1023.    or (Node^.vDataPtr = Nil)
  1024.    or (Node^.vSize = 0)  then
  1025.       GetLongStr := ''
  1026.    else
  1027.    begin
  1028.       Move(mem[seg(Node^.vDataPtr^):ofs(Node^.vDataPtr^)],Info,sizeof(Info));
  1029.       if Info.FileName = NoFiles then
  1030.          GetLongStr := 'No matching files found'
  1031.       else
  1032.          GetLongStr := LongName(Info);
  1033.    end;
  1034. end; {FileDLLOBJ.GetLongStr}
  1035.  
  1036. procedure FileDLLOBJ.GetFileRecord(var FileInfo:tFileInfo; Item:longint);
  1037. {}
  1038. var
  1039.    Node:DLLNodePtr;
  1040. begin
  1041.    Node := NodePtr(Item);
  1042.    if (Node = Nil)
  1043.    or (Node^.vDataPtr = Nil)
  1044.    or (Node^.vSize = 0)  then
  1045.       FileInfo.FileName := ''
  1046.    else
  1047.       Move(mem[seg(Node^.vDataPtr^):ofs(Node^.vDataPtr^)],FileInfo,sizeof(FileInfo));
  1048. end; {FileDLLOBJ.GetFileRecord}
  1049.  
  1050. function FileDLLOBJ.GetFileMask:string;
  1051. {}
  1052. begin
  1053.    GetFileMask := vFileMasks;
  1054. end; {FileDLLOBJ.GetFileMask}
  1055.  
  1056. procedure FileDLLOBJ.SetFileDetails(FileMasks:string; FileAttrib: word);
  1057. {}
  1058. begin
  1059.    if FileMasks = '' then
  1060.       FileMasks := '*.*';
  1061.    vFileMasks := FileMasks;
  1062.    vFileAttrib := FileAttrib;
  1063. end; {FileDLLOBJ.SetFileDetails}
  1064.  
  1065. procedure FileDLLOBJ.FillList;
  1066. {}
  1067. var
  1068.   FileDetails: SearchRec;
  1069.   FileInfo: tFileInfo;
  1070.   TotMasks: byte;
  1071.   Mask: string;
  1072.   RecSize: byte;
  1073.   ECode : integer;
  1074.  
  1075.   procedure SaveFileDetails(IsDir:boolean);
  1076.   begin
  1077.      if FileDetails.Name <> '.' then
  1078.      begin
  1079.         with FileInfo do
  1080.         begin
  1081.             FileName := FileDetails.Name;
  1082.             Attr := FileDetails.Attr;
  1083.             Time := FileDetails.Time;
  1084.             Size := FileDetails.Size;
  1085.             LoadID := succ(vTotalNodes);
  1086.         end;  {with}
  1087.         Ecode := Add(FileInfo,RecSize);
  1088.         if Ecode = 0 then
  1089.           vActiveNodePtr^.SetStatus(1,IsDir);
  1090.      end;
  1091.   end; {SaveFileDetails}
  1092.  
  1093.   procedure ProcessFiles(Attrib:word);
  1094.   {}
  1095.   var I : integer;
  1096.   begin
  1097.      for I := 1 to TotMasks do
  1098.      begin
  1099.         if Attrib = Directory then   {1.00c}
  1100.            Mask := '*.*'
  1101.         else
  1102.            Mask := ExtractWords(I,1,vFileMasks);
  1103.         FindFirst(Mask,Attrib,FileDetails);
  1104.         while DOSError = 0 do
  1105.         begin
  1106.            if (Attrib <> Directory) then
  1107.               SaveFileDetails(false)
  1108.            else if ((Attrib = Directory) and (FileDetails.Attr = Directory)) then
  1109.               SaveFileDetails(true);
  1110.            FindNext(FileDetails);
  1111.         end;
  1112.         if Attrib = Directory then   {1.00c}
  1113.            exit;
  1114.      end;
  1115.   end; {ProcessFiles}
  1116.  
  1117. begin
  1118.    RecSize := sizeof(FileInfo);
  1119.    if vStartNodePtr <> Nil then
  1120.       EmptyList;
  1121.    TotMasks := WordCnt(vFilemasks);
  1122.    if ((vFileAttrib and Directory) = Directory) then
  1123.    begin
  1124.       ProcessFiles(Directory);
  1125.       if vFileAttrib <> Directory then {1.00a}
  1126.          ProcessFiles(vFileAttrib and (Anyfile-Directory-VolumeID));
  1127.    end
  1128.    else
  1129.       ProcessFiles(vFileAttrib);
  1130.    if vTotalNodes = 0 then
  1131.    begin
  1132.       FileInfo.Filename := NoFiles;
  1133.       FileInfo.Time := 0;
  1134.       Ecode := Add(FileInfo,RecSize);
  1135.    end;
  1136.    vSorted := (vSortID = 0) and (vSortAscending = true);
  1137. end; {FileDLLOBJ.FillList}
  1138.  
  1139. procedure FileDLLOBJ.FillNewMask(FileMasks:string);
  1140. {}
  1141. begin
  1142.    SetFileDetails(FileMasks,vFileAttrib);
  1143.    FillList;
  1144. end; {FileDLLOBJ.FillNewMask}
  1145.  
  1146. function FileDLLOBJ.WrongOrder(Node1,Node2:DLLNodePtr;Asc:boolean): boolean;
  1147. {}
  1148. var F1,F2: tFileInfo;
  1149.     P: integer;
  1150.     Name1,Name2: string[8];
  1151.     Ext1,Ext2: string[3];
  1152.  
  1153.     function Name(F:tFileInfo):string;
  1154.     {}
  1155.     begin
  1156.        P := pos('.',F.FileName);
  1157.        if P = 0 then
  1158.           Name := F.FileName
  1159.        else
  1160.           Name := copy(F.FileName,1,pred(P));
  1161.     end;{Name}
  1162.  
  1163.     function Ext(F:tFileInfo):string;
  1164.     {}
  1165.     begin
  1166.        P:= pos('.',F.FileName);
  1167.        if P = 0 then
  1168.           Ext := ''
  1169.        else
  1170.           Ext := copy(F.FileName,succ(P),3);
  1171.     end; {Ext}
  1172.  
  1173. begin
  1174.    fillchar(F1,sizeof(F1),#0);
  1175.    fillchar(F2,sizeof(F2),#0);
  1176.    if Asc then
  1177.    begin
  1178.       GetNodeData(Node1,F1);
  1179.       GetNodeData(Node2,F2);
  1180.    end
  1181.    else
  1182.    begin
  1183.       GetNodeData(Node1,F2);
  1184.       GetNodeData(Node2,F1);
  1185.    end;
  1186.    case vSortID of
  1187.       0: WrongOrder := (F1.LoadID > F2.LoadID);  {DOS}
  1188.       1: begin                                    {NAME}
  1189.             Name1 := Name(F1);
  1190.             Name2 := Name(F2);
  1191.             if (Name1 = Name2) then
  1192.                WrongOrder := (Ext(F1) > Ext(F2))
  1193.             else
  1194.                WrongOrder := (Name1 > Name2);
  1195.       end;
  1196.       2: begin                                    {EXT}
  1197.             Ext1 := Ext(F1);
  1198.             Ext2 := Ext(F2);
  1199.             if Ext1 = Ext2 then
  1200.                WrongOrder := (Name(F1) > Name(F2))
  1201.             else
  1202.                WrongOrder := (Ext1 > Ext2);
  1203.       end;
  1204.       3: WrongOrder := (F1.Size > F2.Size);      {SIZE}
  1205.       4: WrongOrder := (F1.Time > F2.Time);      {TIME}
  1206.       else WrongOrder := false;
  1207.    end; {case}
  1208. end; {FileDLLOBJ.WrongOrder}
  1209.  
  1210. procedure FileDLLOBJ.SwapNodes(Node1,Node2:DLLNodePtr);
  1211. {}
  1212. var 
  1213.   FileInfo: tFileInfo;
  1214.   Size: longint;
  1215.   Status1: byte;
  1216. begin
  1217.    Status1 := Node1^.GetStatusByte;
  1218.    Node1^.SetStatusByte(Node2^.GetStatusByte);
  1219.    Node2^.SetStatusByte(Status1);
  1220.    GetNodeData(Node1,FileInfo);
  1221.    Size := sizeof(FileInfo);
  1222.    Move(Node2^.vDataPtr^,Node1^.vDataPtr^,size);
  1223.    Move(FileInfo,Node2^.vDataPtr^,size);
  1224. end; {FileDLLOBJ.SwapNodes}
  1225.  
  1226. destructor FileDLLOBJ.Done;
  1227. {}
  1228. begin
  1229.    DLLOBJ.Done;
  1230. end; {FileDLLOBJ.Done}
  1231. {|||||||||||||||||||||||||||||||||||||||||||||||}
  1232. {                                               }
  1233. {     U N I T   I N I T I A L I Z A T I O N     }
  1234. {                                               }
  1235. {|||||||||||||||||||||||||||||||||||||||||||||||}
  1236. procedure LinkInit;
  1237. {initilizes objects and global variables}
  1238. begin
  1239. end;
  1240.  
  1241. {end of unit}
  1242. {$ifNDEF OVERLAY}
  1243. begin
  1244.    LINKInit;
  1245. {$ENDif}
  1246. end.
  1247.